package spring.core.aop.jdkproxy;

import jdk.nashorn.internal.objects.annotations.Getter;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import org.springframework.aop.support.AopUtils;
import org.springframework.util.ReflectionUtils;

/**
 * @author 1203056
 * @version Id: JdkDynamicProxyDemo.java, v 0.1 2021-09-05 22:03 1203056 Exp $
 */
public class JdkDynamicProxyDemo {

    public static void main(String[] args) {

        ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
        StudentService targetImpl  = new StudentServiceImpl("hello");
        MyInvocationHandler myHandler = new MyInvocationHandler(targetImpl);
        StudentService proxy = (StudentService) Proxy.newProxyInstance(contextClassLoader, new Class<?>[] { StudentService.class },myHandler);

        System.out.println(AopUtils.isJdkDynamicProxy(proxy));
        System.out.println(Proxy.isProxyClass(proxy.getClass()));

        //获取jdk被代理对象
        Object target = null;
        if(Proxy.isProxyClass(proxy.getClass())){
            InvocationHandler invocationHandler = Proxy.getInvocationHandler(proxy);
            if(invocationHandler instanceof MyInvocationHandler){
                MyInvocationHandler handler = (MyInvocationHandler)invocationHandler;
                target = handler.getTarget();
            }
        }

        System.out.println(target == targetImpl);



        //        proxy.echo("hello");
        //        System.out.println(System.identityHashCode(proxy));
        //        System.out.println(System.identityHashCode(proxy));
    }

    static class MyInvocationHandler implements InvocationHandler {
        public Object getTarget() {
            return target;
        }

        private final Object target;

        MyInvocationHandler(Object target) {
            this.target = target;
        }

        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("invoke method: " + method);
            if (ReflectionUtils.isToStringMethod(method)) {
                return proxy.getClass().toString();//method.invoke(target,args);
            } else if (ReflectionUtils.isHashCodeMethod(method)) {
                return System.identityHashCode(proxy);
            }
            //                System.out.println("proxy ==="+proxy);
            if (method.getDeclaringClass() == StudentService.class) {
                System.out.println("before ......");
                return null;//method.invoke(target,args);
            }
            return null;
        }
    }
}
